package com.gcs.demo.aop;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.gcs.demo.annotation.CheckRequireParam;
import com.gcs.demo.exception.ParamNotRequire;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

@Component
@Aspect
public class CheckRequireParamAop {

    @Pointcut("@annotation(com.gcs.demo.annotation.CheckRequireParam)")
    public void insertPoint(){

    }

    @Around("insertPoint()")
    public Object checkParam(ProceedingJoinPoint proceedingJoinPoint){
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        MethodSignature signature = (MethodSignature)proceedingJoinPoint.getSignature();
        CheckRequireParam annotation = signature.getMethod().getAnnotation(CheckRequireParam.class);
        String[] checkParams = annotation.requireParam();
        try {
            Map<String,String> parameterMap = getRequestParams(request);
            //当规定了必传参数，获取到的参数里面是空的，这里就直接抛出异常
            if(checkParams.length > 0 && (parameterMap == null || parameterMap.size() == 0)){
                throw new ParamNotRequire("当前获取到的参数为空");
            }
            Arrays.stream(checkParams).forEach(item ->{
                if(!parameterMap.containsKey(item)){
                    throw new ParamNotRequire("参数[" + item + "]不存在");
                }
                if(!StringUtils.hasLength(parameterMap.get(item))){
                    throw new ParamNotRequire("参数[" + item + "]不能为空");
                }
            });
            Object proceed = proceedingJoinPoint.proceed();
            return proceed;
        } catch (Throwable throwable) {
            if(throwable instanceof ParamNotRequire){
                throw (ParamNotRequire)throwable;
            }
            throwable.printStackTrace();
        }
        return null;
    }

    public Map<String,String> getRequestParams(HttpServletRequest request) throws IOException {
        Map<String,String> resultParam = null;
        if(request.getMethod().equalsIgnoreCase("POST")){
            StringBuffer data = new StringBuffer();
            String line = null;
            BufferedReader reader = request.getReader();
            while (null != (line = reader.readLine()))
                data.append(line);
            if(data.length() != 0) {
                resultParam = JSONObject.parseObject(data.toString(), new TypeReference<Map<String,String>>(){});
            }
        }else if(request.getMethod().equalsIgnoreCase("GET")){
            resultParam = request.getParameterMap().entrySet().stream().collect(Collectors.toMap(i -> i.getKey(), e -> Arrays.stream(e.getValue()).collect(Collectors.joining(","))));
        }
        return resultParam != null ? resultParam : new HashMap();
    }
}
